package sqlstore

import (
	//"os"
	"fmt"
	"path/filepath"
	"github.com/astaxie/beego"

	"github.com/astaxie/beego/config"
	"github.com/jmoiron/sqlx"
	_ "github.com/lib/pq"
)

var (
	//为了支持多种数据库源, 加上一个map用于存储多个DB
	dbs = make(map[string]*sqlx.DB)

	ef = fmt.Errorf
	sf = fmt.Sprintf

	dbConfig config.Configer
)

const (
	ActiveDBName  = "dbname"
	RunMode = "runmode"
)


// 模块的初始化
func init() {

}

//通过读取配置文件,然后重新创建数据库连接.
func createDB() {
	currentPath, _ := filepath.Abs(".")
	configPath := filepath.Join(currentPath, "conf", "datasource.json")
	dbConfig, err := config.NewConfig("json", configPath)
	beego.Debug(fmt.Sprintf(" the app path is: %s \n", configPath))

	if err != nil {
		beego.Debug(fmt.Sprintf(" cannot get json config %s \n", err.Error()))
		return
	}

	rootArray, err := dbConfig.DIY("rootArray")
	if err != nil {
		beego.Debug(" can not find database config")
		return
	}
	rootArrayCasted := rootArray.([]interface{})
	for _, dbConfigItem := range (rootArrayCasted) {
		elem := dbConfigItem.(map[string]interface{})
		dbType, dbName, dbConStr := elem["type"].(string), elem["name"].(string), elem["connstr"].(string)
		db, err := sqlx.Connect(dbType, dbConStr)
		if err == nil {
			dbs[dbName] = db
			db.SetMaxIdleConns(int(elem["maxIdle"].(float64)))
			db.SetMaxOpenConns(int(elem["maxOpen"].(float64)))
			beego.Debug(fmt.Sprintf("the db %s create success\n", dbName))
		} else {
			beego.Error(err)
		}
	}

}


//根据给定数据库名称,获取一个DB
func GetDB(dbName string) (*sqlx.DB, error) {
	beego.Info(dbName)
	selectedDB, ok := dbs[dbName]
	var err error

	if !ok {
		beego.Info("can no found the db, then create new db")
		createDB()
		selectedDB = dbs[dbName]
	}

	if selectedDB == nil {
		err = ef("没有发现要找的数据库!")
		beego.Error(err)
	}

	return selectedDB, err
}

func GetActiveDbName() string {
	activeDB := beego.AppConfig.String(ActiveDBName)
	fmt.Printf("active db name :%s\n", activeDB)
	return activeDB
}

func GetTx() *sqlx.Tx {
	beego.Info("the active db config is : %s" , GetActiveDbName())
	db, _ := GetDB(GetActiveDbName())
	tx := db.MustBegin()
	return tx
}

